#include <iostream>
#include <math.h>
#include "DDDummyData.hh"
#include "DDEventManager.hh"
#include "TH1F.h"
#include "TCanvas.h"
#include "TObject.h"
#include "TROOT.h"

using namespace std;

DDDummyData::DDDummyData() {
  m_DataEventID = -1;
  header = new specific_header();
}

DDDummyData::~DDDummyData() 
{
  delete header;
}

void DDDummyData::TearDown() {}

int DDDummyData::Initialize()
{
  data_file = new fstream("dummy_data", ios::in | ios::binary );
	if (!(data_file))
	  {
	    cout << "data file error in DDDummyData::Initialize" << endl;
	    return -1;		
	  }
	
	header->read_header(data_file);
	
	TH1F* temp;
	set<int>::iterator it;
	for(it=(*(header->get_channels())).begin(); it!=(*(header->get_channels())).end(); ++it)
	{
		cout << "NUMDOGCHAN" << endl;
		current_trace.insert(pair<int,TH1F*>(*it, temp));
	}

	map<int,TH1F*>::iterator ch_it;
	for(ch_it=current_trace.begin(); ch_it!=current_trace.end(); ++ch_it)
	{
		double initial_time = header->get_trigger_offset(ch_it->first);
		double final_time = header->get_trigger_offset(ch_it->first) + header->get_samples_per_trace(ch_it->first) * header->get_time_per_sample(ch_it->first);
	
		ch_it->second = new TH1F("Current Trace", "Current Trace", header->get_samples_per_trace(ch_it->first), initial_time, final_time); 
	}

	return DDEventManager::kOK;
}


int DDDummyData::GoToEvent(int n)
{


	cout << "EVENT N: " << n << endl;
	
	if (n>=header->get_num_traces())
	{
		cout << "n: " << n << " is too large. There are only " << header->get_num_traces() << " traces!" << endl;
		return -1;
	}
	cout << "HEADSIZE " << header->header_size << endl;
	cout << "TRACESIZE " << header->trace_size << endl;

	data_file->seekg(header->header_size + n * header->trace_size * header->get_num_channels());
	cout << "GET POINTER " << header->header_size + n * header->trace_size << endl;

	unsigned short int adc_count;
	double voltage;

	double voltage_range;

	set<int>::iterator channel;

	for(channel=(*(header->get_channels())).begin(); channel!=(*(header->get_channels())).end(); ++channel)
	{
		cout << "NUMDOGCHAN" << endl;
	//cout << "CHANN: " << header.get_channels().size() << endl;
	double current_time = header->get_trigger_offset(*channel);
		voltage_range = header->get_volts_per_sample(*channel) * (pow(2,header->get_bits_per_sample(*channel)) - 1);
		cout << "VRANGE: " << voltage_range << endl;
		cout << "ROO: " << header->get_samples_per_trace(*channel) << endl;
		for(int sample=0; sample<header->get_samples_per_trace(*channel); sample++)

		{
			//##### ADD SUPPORT FOR MULTIPLE BIT WIDTHS#####//
			data_file->read((char*)&adc_count, sizeof(adc_count));

			voltage = (adc_count) * header->get_volts_per_sample(*channel) + header->get_voltage_offset(*channel) - voltage_range/2; 

//			cout << *channel<<" " << adc_count << endl;
//			cout << *channel<<" " << voltage << endl;

			current_trace[*channel]->SetBinContent(current_time, voltage);

			current_time+=header->get_time_per_sample(*channel);
		}
	}	

	return DDEventManager::kOK;
}	


int DDDummyData::specific_header::add_channel(int channel_arg)
{
    if (channel_arg<=4)
    {
        channels.insert(channel_arg);
    }

    else
    {
        cout << "CHANNEL OUT OF RANGE. DUMMY HAS 4 CHANNELS" << endl;
        return (-1);
    }
}

int DDDummyData::specific_header::remove_channel(int channel_arg)
{
    if (channel_arg<=4)
    {
        channels.erase(channel_arg);
    }

    else
    {
        cout << "CHANNEL OUT OF RANGE. DUMMY HAS 4 CHANNELS" << endl;
        return (-1);
    }
}




void DDDummyData::specific_header::read_header(fstream* data_file)
{
	data_file->read((char*)&num_traces, sizeof(num_traces));
	data_file->read((char*)&num_channels, sizeof(num_channels));

	trace_size = 0;

	int channel;


	for(int i=0; i<num_channels; i++)
	{
		data_file->read((char*)&channel, sizeof(channel));
		data_file->read((char*)&samples_per_trace[channel], sizeof(samples_per_trace[channel]));
		data_file->read((char*)&bits_per_sample[channel], sizeof(bits_per_sample[channel]));
		data_file->read((char*)&time_per_sample[channel], sizeof(time_per_sample[channel]));
		data_file->read((char*)&trigger_offset[channel], sizeof(trigger_offset[channel]));
		data_file->read((char*)&volts_per_sample[channel], sizeof(volts_per_sample[channel]));
		data_file->read((char*)&voltage_offset[channel], sizeof(voltage_offset[channel]));

		channels.insert(channel);

		//Calculate_trace_size
		trace_size += samples_per_trace[channel] * (bits_per_sample[channel]/8);
	}	
		
	header_size = data_file->tellg();

	cout << "Header size: " << header_size << endl;
	cout << "Trace size: " << trace_size << endl;

}







